package com.csii.test;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;



public class Util {
	
	public static String certPath = "F:\\SignatureTestDemo\\src\\ddbank_test.pfx";//私钥路径
	public static String certPassword = "123456";//私钥密码
	public static String publicKeyPath = "F:\\SignatureTestDemo\\src\\ddbank_test.cer";//公钥路径
	
	
	
//	public static String certPath = "/home/cert/商户私钥_prod.pfx";//私钥路径
//	public static String certPassword = "111111";//私钥密码
//	public static String publicKeyPath = "/home/cert/商户公钥_prod.cer";//公钥路径
	
	/**s
	 * 对网关数据签名
	 * @param plain
	 * @return
	 */
	public static  String signPaygateData(String plain) throws Exception {
	    String signatureAlgorithm = "MD5withRSA";
	    //String keyAlias="keytest";
	    String keyAlias="ddbank";
	    
	    KeyReader keyReader = new KeyReader();
	    //使用pfx加签
	    PrivateKey privateKey = keyReader.readPrivateKeyfromPKCS12StoredFile(certPath, certPassword);
	    
		byte[] signature = null;
		System.out.println("privateKey=========="+privateKey);
		try {
			signature =	sign(privateKey, signatureAlgorithm, plain.getBytes("UTF-8"));
					
		} catch (Exception e) {
			throw new Exception(e);
		}
		return Hex2Byte.byte2Hex(signature);
	}
	
	public static byte[] sign(PrivateKey paramPrivateKey, String paramString,
			byte[] paramArrayOfByte) throws Exception {
		Signature localSignature = Signature.getInstance(paramString);
		localSignature.initSign(paramPrivateKey);
		localSignature.update(paramArrayOfByte);
		return localSignature.sign();
	}
	
	/**
	 * 使用MD5withRSA算法对签名进行验证
	 * @param plain 交易数据明文
	 * @param signature 交易签名
	 * @param publicKey 公钥
	 * @return 验证签名是否正确
	 * @throws Exception 
	 */
	public static boolean verifyByMD5withRSA(String plain, String signature, PublicKey publicKey) throws Exception {
		final String MD5WITHRSA_ALGORITHM = "MD5withRSA";
		return verify(plain, signature, MD5WITHRSA_ALGORITHM, publicKey);
	}
	
	/**
	 * 验证16进制签名
	 * @param plain 交易数据明文
	 * @param signature 签名
	 * @param algorithm 签名算法
	 * @param publicKey java.security.PublicKey 公钥
	 * @return 验证是否成功
	 * @throws Exception 
	 */
	public static boolean verify(String plain, String signature, String algorithm, PublicKey publicKey) throws Exception {
		try {
			notNull(plain, " plain is null.");
			notNull(signature, "signature is null.");
			notNull(algorithm, "algorithm is null.");
			notNull(publicKey, "public key is null.");
			
			java.security.Signature sign = java.security.Signature.getInstance(algorithm);
			sign.initVerify(publicKey);
			sign.update(plain.getBytes());
			byte[] signatureByteArray = hexToByte(signature); //转换为字节数组
			return sign.verify(signatureByteArray);
		} catch (Exception ex) {
			throw new Exception();
		}
	}
	
	
	/**
	 * 判断输入对象是否不为null，如果为null抛出<code>IllegalArgumentException</code>异常
	 * @param object 输入对象
	 * @param message 异常信息
	 */
	public static void notNull(Object object, String message) {
		if (object == null) {
			throw new IllegalArgumentException(message);
		}
	}
	
	/**
	 * 将16进制字符串转换为字节数组
	 * 算法： 每2位为一个字符，将该16进制字符转换为字节
	 * 
	 * @param hexString 16进制字符串
	 * @return 字符数组
	 */
	private static byte[] hexToByte(String hexString) {
		if (hexString == null || hexString.trim().length() == 0) {
			return new byte[0];
		}
		//按2位计算字符个数
		int unit = hexString.length() / 2;
		//结果字符数组，初始长度为unit
		byte[] byteArray = new byte[unit];

		for (int i = 0; i < hexString.length() / 2; i++) {
			//截取字符
			String hexChar = hexString.substring(i * 2, i * 2 + 2);
			//将16进制转换为字节
			byteArray[i] = (byte) Integer.parseInt(hexChar, 16);
		}
		return byteArray;
	}
	
	
	/**
	 * 获取公钥证书内容
	 * @param pubKeyFile
	 * @return
	 */
	public static PublicKey getPubKeyStr(String pubKeyFile){
		PublicKey publicKey1 = loadPubkey(pubKeyFile);
//		PublicKey publicKey1 = loadPubkeyByByte();
//		return Base64.encodeBase64String(publicKey1.getEncoded());
		return publicKey1;
	}
	
	public static PublicKey loadPubkey(String pubkeyfile){
		System.out.println("加载验签证书==>" + pubkeyfile);
		CertificateFactory cf = null;
		FileInputStream in = null;
		try {
			cf = CertificateFactory.getInstance("X.509");
			in = new FileInputStream(pubkeyfile);
			X509Certificate validateCert = (X509Certificate) cf.generateCertificate(in);
			return validateCert.getPublicKey();
		}catch (CertificateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static PublicKey loadPubkeyByByte(){
		String sCart="-----BEGIN CERTIFICATE-----MIIDoTCCAomgAwIBAgIQEAAAAAAAAAAAAAAQASCCdTANBgkqhkiG9w0BAQUFADAbMQswCQYDVQQGEwJDTjEMMAoGA1UEChMDQk9DMB4XDTE0MTEwNTAzNDQwNloXDTE1MTEwNTAzNDQwNlowgYExCzAJBgNVBAYTAmNuMRUwEwYDVQQKEwxDRkNBIFRFU1QgQ0ExDzANBgNVBAsTBkNDRkNDQjEUMBIGA1UECxMLRW50ZXJwcmlzZXMxNDAyBgNVBAMUKzA0MUA4MzEzMjI2MDA5MDAwMDIwMDAwMDIyNTE1QGRkc2hAMDAwMDAwMzgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKTLTFQIJnUGk+XFRwu6t+hPh60T/NZQVVAwWKOjhwz1EuhWSMVJiHFya7rVsXxhmmIz+RzBDO5Ce4xi0+4lRIPvGPa2mUNG8fcPjCtXC8BQyicfvAWCqiyKpPekN7grczt3HYV2/Y+DhXKXuulVkNqBn5Bxf8xLuw9kpt6++/hfAgMBAAGjgf0wgfowHwYDVR0jBBgwFoAUz3CdYeudfC6498sCQPcJnf4zdIAwSAYDVR0gBEEwPzA9BghggRyG7yoBATAxMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmNmY2EuY29tLmNuL3VzL3VzLTE0Lmh0bTA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vdWNybC5jZmNhLmNvbS5jbi9SU0EvY3JsMTM1My5jcmwwEgYDVR0RBAswCYEHMUAxLmNvbTALBgNVHQ8EBAMCA+gwHQYDVR0OBBYEFDJt8vrS/5ZyLe1WVgBuT/J2nwEiMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQAzoA7MB0bmu3SzKCSwcGT7MXUqOeg/jFGW2hPzroRM11E8GM1CapLdBa9XFHLdqNQkB+8G/fsgu9+O5HDSXWQnFMpyoefw3yUuH4Xdmx/6fmWSwMMbbpIGanQ6lMxTaMWi7ZE8sRTM4LQU2GUZrgSyC67cB7ORkJ4fLje5I+axFR9WAlh5Uzy1vXmlRIEtx/n1AHnpkHHe+XqITFOGJBc1nWDRkLDp3oyIbntXU0TbVBIZ5tcyrfAu1D6ITzIngJ1G7ZtwzdERirb8Jhg1sijDIsmxEqH9MPv39il9BjkEszNibqWpao4Yql1vF4lfKfiI3OlhwBbV7Q968qdftgh8-----END CERTIFICATE-----";
		BufferedInputStream is = new BufferedInputStream(new ByteArrayInputStream(sCart.getBytes()));
        CertificateFactory cf;
        try {
            cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
            return cert.getPublicKey();
        } catch (CertificateException e) {
            System.out.println(
                    "停车场编号证书格式错误,证书内容[" + sCart + "]");
            System.out.println(e.getMessage());
            
        }
       return null;
	}
	
	
}
